package com.yu.juc;

import java.util.concurrent.Semaphore;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * @Author Irelia
 * @Date 2024/7/5 10:53
 * 用3个线程交替打印 1 - 20 ， A 1, B 2, C 3, A 4, B 5, C 6, ...
 * 通过Semaphore实现，通过acquire阻塞 和 release释放来实现
 */
public class SemaphoreDemo {
    public final int max;
    private final Semaphore semaphoreA = new Semaphore(1);
    private final Semaphore semaphoreB = new Semaphore(0);
    private final Semaphore semaphoreC = new Semaphore(0);

    private final AtomicInteger currentNumber = new AtomicInteger(1); // 用于跟踪当前打印的数字

    public SemaphoreDemo(int max) {
        this.max = max;
    }

    public void printA() {
        print("A", semaphoreA, semaphoreB);
    }

    public void printB() {
        print("B", semaphoreB, semaphoreC);
    }

    public void printC() {
        print("C", semaphoreC, semaphoreA);
    }

    /**
     * 具体步骤，ABC三条线程同时开始。
     * 因为A线程设了信号量为1，所以acquire()不会阻塞，BC在阻塞，A先打印，然后释放B的信号量
     *
     */
    public static void main(String[] args) {
        SemaphoreDemo printer = new SemaphoreDemo(10);
        Thread t1 = new Thread(printer::printA, "Thread A");
        Thread t2 = new Thread(printer::printB, "Thread B");
        Thread t3 = new Thread(printer::printC, "Thread C");

        t1.start();
        t2.start();
        t3.start();
    }


    private void print(String alphabet, Semaphore currentSemaphore, Semaphore nextSemaphore) {
        while (true) {
            try {
                currentSemaphore.acquire();
                if (currentNumber.get() > max) {
                    nextSemaphore.release(); // 确保其他线程不被阻塞
                    break;
                }
                System.out.println(alphabet + ": " + currentNumber.get());
                currentNumber.getAndIncrement();
                nextSemaphore.release();
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
                return;
            }
        }
    }
}
